/**
 * Copyright:Copyright(c)2014-2017
 * Company:厦门市易致达物联网科技有限公司
 *
 * @version 1.0
 */
package shop.controller.front.orderpay;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import shop.core.FrontBaseController;
import shop.core.RequestHolder;
import shop.core.Services;
import shop.core.common.bean.JSONResult;
import shop.core.plugins.wxpay.WXPay;
import shop.core.plugins.wxpay.WXPayConfigImpl;
import shop.core.plugins.wxpay.WXPayConstants;
import shop.core.plugins.wxpay.WXPayUtil;
import shop.core.util.AddressUtils;
import shop.services.front.brokerage.BrokerageService;
import shop.services.front.brokerage.bean.Brokerage;
import shop.services.front.order.OrderService;
import shop.services.front.order.bean.Order;
import shop.services.front.orderdetail.OrderdetailService;
import shop.services.front.orderdetail.bean.Orderdetail;
import shop.services.front.orderpay.OrderpayService;
import shop.services.front.orderpay.bean.Orderpay;
import shop.services.front.product.ProductService;
import shop.services.front.product.bean.Product;
import shop.services.front.spec.SpecService;
import shop.services.front.spec.bean.Spec;
import shop.services.front.systemSetting.SystemSettingService;
import shop.services.front.systemSetting.bean.SystemSetting;
import shop.services.manage.system.bean.User;
import shop.services.manage.system.impl.UserService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @类名称：OrderpayController
 * @创建人：Ltz
 * @创建时间：2017-09-20 下午15:50:16
 * @版本号：1.0
 * @描述：
 */
@Controller
@RequestMapping("/front/orderpay/")
public class OrderpayController extends FrontBaseController<Orderpay> {
    @Resource
    private OrderpayService orderpayService;
    @Resource
    private OrderService orderService;
    @Resource
    private ProductService productService;
    @Resource
    private SpecService specService;
    @Resource
    private SystemSettingService systemSettingService;
    @Resource
    private OrderdetailService orderdetailService;
    @Resource
    private BrokerageService brokerageService;
    @Resource
    private UserService userService;

    private WXPay wxpay;
    private WXPayConfigImpl config;

    @Override
    public Services<Orderpay> getService() {
        return orderpayService;
    }


    /**
     * 获取预支付信息
     *
     * @param session
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "getPrepayId", method = RequestMethod.GET)
    @ResponseBody
    public JSONResult getPrepayId(HttpSession session, Order order) throws Exception {
        JSONResult jsonResult = new JSONResult();
        order.setStatus("init");
        String out_trade_no = UUID.randomUUID().toString().replace("-", "");//商户订单号
        String orderID = "";
        DecimalFormat df = new DecimalFormat("######0.00");//格式化数据
        // 为订单支付时插入订单
        User user = (User) session.getAttribute("userInfo");//获取登陆用户
        if (user == null)
            return JSONResult.error("您还未进行授权，无法购物");
        BigDecimal totalFee = order.getPtotal();
        logger.debug("订单总价：" + totalFee);
        if (!StringUtils.isBlank(order.getId())) {
            logger.debug("已有订单："+ order.getId());
            orderID = order.getId();
            order = orderService.selectById(order.getId());//查询订单记录
        } else {
            logger.debug("插入订单：");
            String[] productIDs = order.getProductIDs().split(",");
            String[] specIDs = order.getSpecIDs().split(";");
            String[] productAmount = order.getProductAmount().split(",");
            for (int i = 0; i < productIDs.length; i++) {
                logger.debug("查询产品库存：");
                Spec spec = new Spec();
                spec.setProductID(productIDs[i]);
                spec.setSpecCombination(specIDs[i]);
                spec = specService.selectOne(spec);//查询该件商品库存
                Product rs = new Product();
                rs.setId(productIDs[i]);
                rs = productService.selectOne(rs);//查询该件商品
                if ((spec.getSpecStock() - Integer.parseInt(productAmount[i])) <= 0)
                    return JSONResult.error(rs.getName() + "商品库存不足，请重新下单!");
            }
            order.setUserID(user.getId());
            orderID = String.valueOf(orderService.insert(order));
            logger.debug("商品ID为：" + order.getProductIDs());
        }
        config = WXPayConfigImpl.getInstance();
        wxpay = new WXPay(config);
        Float rs = order.getPtotal().floatValue()*100;
        String total_fee=String.valueOf(rs.intValue());//商品总价
        logger.debug("商品总价为：" + total_fee);
        logger.debug("订单号为：" + out_trade_no);
        HashMap<String, String> data = new HashMap<String, String>();
        data.put("body", "佰信恒通");//商品描述
        data.put("out_trade_no", out_trade_no);//商户订单号
        data.put("device_info", "");//设备号
        data.put("total_fee", total_fee);//标价金额
        String clientIp = AddressUtils.getIp(RequestHolder.getRequest()).split(",")[0];
        data.put("spbill_create_ip", clientIp);//终端IP
        data.put("notify_url", "http://www.etexian.cn/rest/front/orderpay/notify");//通知地址
        data.put("trade_type", "JSAPI");//交易类型
        data.put("product_id", UUID.randomUUID().toString().replace("-", ""));//商品ID
        data.put("openid", session.getAttribute("userOpenId").toString());//用户标识
        logger.debug("data数据信息："+data);
        try {
            Map<String, String> r = wxpay.unifiedOrder(data);
            logger.debug("获得预支付信息为：" + r.get("return_msg") + ",获得返回状态码为：" + r.get("return_code"));
            //回传页面参数
            Map<String, String> reqData = new HashMap<String, String>();
            reqData.put("appId", config.getAppID());//公众账号ID
            reqData.put("timeStamp", String.valueOf(new Date().getTime() / 1000));//生成签名的时间戳
            reqData.put("nonceStr", r.get("nonce_str"));//随机字符串
            reqData.put("signType", "MD5");//签名类型
            reqData.put("package", "prepay_id=" + r.get("prepay_id"));//预支付交易会话标识
            String paySign = WXPayUtil.generateSignature(reqData, config.getKey(), WXPayConstants.SignType.MD5);//获取微信支付签名
            reqData.put("paySign", paySign);//签名
            logger.debug("回传页面参数填写完成："+reqData);
            //在本地插入订单支付信息
            logger.debug("在本地插入订单支付信息");
            Orderpay orderpay = new Orderpay();
            orderpay.setOrderID(orderID);
            //获取支付记录表判断是否存在支付订单
            Orderpay anOrderpay = orderpayService.selectOne(orderpay);
            logger.debug("本地订单支付信息："+anOrderpay);
            if (anOrderpay != null) {
                anOrderpay.setPrepayId(r.get("prepay_id"));//赋值,预支付ID
                anOrderpay.setOutTradeNo(out_trade_no);//赋值,商户订单号
                getService().update(anOrderpay);//更新订单支付信息
                jsonResult.setData(reqData);//回传页面参数
                return jsonResult;
            } else {
                orderpay.setPayStatus("0");//赋值,支付状态
                orderpay.setPrepayId(r.get("prepay_id"));//赋值,预支付ID
                orderpay.setPayType(data.get("trade_type"));//赋值,交易类型
                orderpay.setPayAmount(order.getPtotal());//赋值,支付金额
                orderpay.setOutTradeNo(out_trade_no);//赋值,商户订单号
                orderpay.setProductBody(data.get("body"));//赋值,商品描述
                getService().insert(orderpay);//插入订单支付表
                jsonResult.setData(reqData);//回传页面参数
                return jsonResult;
            }
        } catch (Exception e) {
            logger.debug("打印错误日志：");
            e.printStackTrace();
            jsonResult.setSuccess(false);
            return jsonResult;
        }
    }

    /**
     * 微信支付回调接口
     *
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "notify", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public String payNotifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DecimalFormat df = new DecimalFormat("######0.00");//设定double格式，保留两位小数
        BufferedReader reader = request.getReader();//读取输入字符
        String line = "";
        String xmlString = null;
        StringBuffer inputString = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            inputString.append(line);
        }
        xmlString = inputString.toString();
        request.getReader().close();//关闭输入流
        Map<String, String> receiveData = WXPayUtil.xmlToMap(xmlString);
        logger.debug("收到支付回调结果:" + receiveData);
        String out_trade_no = receiveData.get("out_trade_no");
        logger.debug("商户订单号："+out_trade_no);
        Orderpay orderpay = new Orderpay();
        orderpay.setOutTradeNo(out_trade_no);//赋值,商户订单号
        orderpay = getService().selectOne(orderpay);//查询支付记录
        logger.debug("查询本地支付记录："+orderpay);
        String orderID = orderpay.getOrderID();
        String rsType = receiveData.get("return_code");//返回状态码
        HashMap<String, String> data = new HashMap<String, String>();
        String reStr = "";
        if (rsType.equals("SUCCESS")) {//判断交易是否成功
            Order order = orderService.selectById(orderID);//查询该条订单
            logger.debug("支付返回订单信息："+order.getStatus());
            if (order.getStatus().equals("pass")) {
                data.put("return_code", "SUCCESS");
                data.put("return_msg", "OK");
                reStr = WXPayUtil.mapToXml(data);
                logger.debug("更新本地订单支付表信息："+orderpay);
                orderpay.setTransactionId(receiveData.get("transaction_id"));
                orderpay.setPayStatus("1");
                getService().update(orderpay);
                return reStr;//微信返回的随机字符串（return_code为SUCCESS）
            } else {
                SystemSetting setting = systemSettingService.selectOne(new SystemSetting());//获取佣金比例设定
                BigDecimal totalCommission = new BigDecimal(0.00);//返利金额
                BigDecimal profit = new BigDecimal(0.00);//单件商品利润
                BigDecimal profits = new BigDecimal(0.00);//订单利润
                Orderdetail orderdetail = new Orderdetail();
                orderdetail.setOrderID(orderID);
                List<Orderdetail> orderdetailList = orderdetailService.selectList(orderdetail);//查询订单详情列表
                //遍历订单详情
                for (Orderdetail anOrdedetail : orderdetailList) {
                    Product product = new Product();
                    product.setId(anOrdedetail.getProductID());
                    product = productService.selectOne(product);//查询商品信息
                    logger.debug("商品规格：" + anOrdedetail.getSpecInfo());
                    //更新产品库存
                    Spec spec = new Spec();
                    spec.setProductID(anOrdedetail.getProductID());
                    spec.setSpecCombination(anOrdedetail.getSpecInfo());
                    spec = specService.selectOne(spec);
                    spec.setSpecStock(spec.getSpecStock() - anOrdedetail.getNumber());
                    specService.update(spec);
                    //更新商品销售量
                    product.setSellcount(product.getSellcount() + anOrdedetail.getNumber());
                    productService.update(product);
                    //计算商品利润总值
                    logger.debug("商品进价：" + spec.getSpecPurchasePrice() + "    商品数量" + anOrdedetail.getNumber());
                    profit = spec.getSpecNowPrice().subtract(spec.getSpecPurchasePrice()).multiply(new BigDecimal(anOrdedetail.getNumber()));//计算单件商品利润
                    profits=profits.add(profit);//计算该条订单利润
                    profits=profits.setScale(2, BigDecimal.ROUND_HALF_UP);//格式化数据
                }
                //计算需要分佣的金额
                totalCommission =profits.multiply(setting.getPercent());
                totalCommission=totalCommission.setScale(2, BigDecimal.ROUND_HALF_UP);
                logger.debug("订单总利润："+ profits);
                logger.debug("返利金额："+totalCommission);
                // 更新订单状态
                logger.debug("更新订单状态");
                order.setStatus("pass");
                orderService.update(order);
                //用户上级返佣
                User rs=new User();
                rs.setId(order.getUserID());
                rs=userService.selectOne(rs);//查询登陆用户
                if(!StringUtils.isBlank(rs.getPid())&&!"0.00".equals(totalCommission.toString())){//判断父级是否存在以及返佣金额是否为0
                    Brokerage brokerage = new Brokerage();
                    brokerage.setUserID(rs.getId());
                    brokerage.setAffID(rs.getPid());
                    brokerage.setOrderID(order.getId());
                    brokerage.setMoney(totalCommission);
                    brokerage.setProfit(profits);
                    brokerage.setPercent(setting.getPercent());//赋值
                    brokerageService.insert(brokerage);//插入返利表
                    User rs2=new User();
                    rs2.setId(brokerage.getAffID());
                    rs2=userService.selectOne(rs2);//查询该用户绑定的上级
                    rs2.setWalletMoney(rs2.getWalletMoney().add(totalCommission));//更新返利金额
                    userService.update(rs2);
                }else{}
            }
            //更新本地订单支付表信息
            logger.debug("更新本地订单支付表信息："+orderpay);
            orderpay.setTransactionId(receiveData.get("transaction_id"));
            orderpay.setPayStatus("1");
            getService().update(orderpay);
        }
        data.put("return_code", "SUCCESS");
        data.put("return_msg", "OK");
        reStr = WXPayUtil.mapToXml(data);
        return reStr;
    }
}
